package org.example.AQS;

import java.util.concurrent.locks.AbstractQueuedSynchronizer;

/**
 * 自定义同步器：创建了一个内部类Sync，继承自AbstractQueuedSynchronizer。
 * <p>
 * 尝试获取共享资源：tryAcquireShared方法用于尝试获取共享资源。如果当前状态为0（表示没有其他线程持有资源），则允许当前线程获取资源，并将状态设置为1。
 * <p>
 * 释放共享资源：tryReleaseShared方法用于释放共享资源。在这个简单的例子中，我们将状态重置为0，表示资源已释放。
 * <p>
 * 自定义同步器的使用：MySemaphore类中定义了acquire和release方法，分别用于获取和释放资源。
 * <p>
 * 多线程测试：在main方法中，创建了两个线程来测试同步器。第一个线程先启动，并在一段时间后释放资源，然后第二个线程尝试获取资源。
 * <p>
 * 这个简单的示例演示了如何使用AQS来实现一个信号量（Semaphore），它允许多个线程同时访问资源，但限制了同时访问的数量。
 * 在实际应用中，AQS可以用于实现更复杂的同步器，如重入锁（ReentrantLock）、条件变量（Condition）等。
 */
public class MySemaphore {
    private final Sync sync = new Sync();
    public void acquire() {
        // 获取锁
        sync.acquireShared(1);
    }
    public void release() {
        // 释放锁
        sync.releaseShared(1);
    }
    public static void main(String[] args) throws InterruptedException {
        MySemaphore semaphore = new MySemaphore();
        /**
         * Semaphore信号量，允许多个线程同时访问资源，但限制了同时访问的数量
         */
        // 创建线程
        Thread thread1 = new Thread(() -> {
            semaphore.acquire();
            try {
                System.out.println("Thread is running");
                // 模拟线程执行任务
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            } finally {
                semaphore.release();
                System.out.println("Thread released the semaphore");
            }
        });

        Thread thread2 = new Thread(() -> {
            semaphore.acquire();
            try {
                System.out.println("Thread is running");
            } finally {
                semaphore.release();
            }
        });

        thread1.start();
        // 让第一个线程先执行
        Thread.sleep(500);
        thread2.start();
    }
}